import axios from "axios";
import { getModules } from "./arcgisAPI";
import store from "./store";

export const getCSVData = (url: string) => {
  const promise = new Promise<{ header: string[]; data: any[] }>(
    (resolve, reject) => {
      axios
        .get(url)
        .then(res => {
          if (res.status === 200) {
            try {
              const data = csv2Json(res.data);
              resolve(data);
            } catch (e) {
              reject("构建csv数据失败");
            }
          } else {
            reject("获取csv数据失败");
          }
        })
        .catch(() => {
          reject("获取csv数据失败");
        });
    }
  );
  return promise;
};

const csv2Json = (str: string): { header: string[]; data: any[] } => {
  const jsonData: { header: string[]; data: any[] } = { header: [], data: [] };
  const arr = str.split("\r\n");
  const headerStr = arr[0];
  const header = headerStr.split(",");
  jsonData.header = header;
  for (let i = 1; i < arr.length; i++) {
    const data: any = {};
    const item = arr[i];
    const items = item.split(",");
    header.forEach((el, index) => {
      data[el] = items[index];
    });
    jsonData.data.push(data);
  }
  return jsonData;
};

export const date2format = (_date: Date) => {
  const obj = getTimeObjectByDate(_date);
  const { year, month, date, hours, minutes, seconds } = obj;
  return (
    year +
    "-" +
    month +
    "-" +
    date +
    " " +
    hours +
    ":" +
    minutes +
    ":" +
    seconds
  );
};

export const getTimeObjectByDate = (date: Date) => {
  const year = date.getFullYear();
  const m = date.getMonth() + 1;
  const month = m < 10 ? "0" + m : m;
  const d = date.getDate();
  const _date = d < 10 ? "0" + d : d;
  const h = date.getHours();
  const hours = h < 10 ? "0" + h : h;
  const minute = date.getMinutes();
  const second = date.getSeconds();
  const _minute = minute < 10 ? "0" + minute : minute;
  const _second = second < 10 ? "0" + second : second;
  return {
    year,
    month,
    date: _date,
    hours,
    minutes: _minute,
    seconds: _second
  };
};

export const format2Date = (format: string) => {
  let date = new Date();
  date.setFullYear(parseInt(format.substring(0, 4), 10));
  date.setMonth(parseInt(Number(format.substring(5, 7)) - 1 + "", 10));
  date.setDate(parseInt(format.substring(8, 10), 10));
  date.setHours(parseInt(format.substring(11, 13), 10));
  date.setMinutes(parseInt(format.substring(14, 16), 10));
  date.setSeconds(parseInt(format.substring(17, 19), 10));
  date.setMilliseconds(0);
  return date;
};

export const initformatDate = (date: Date) => {
  const t = new Date(date);
  const y = t.getFullYear();
  const m = t.getMonth() + 1 > 9 ? t.getMonth() + 1 : "0" + (t.getMonth() + 1);
  const d = t.getDate() > 9 ? t.getDate() : "0" + t.getDate();
  return y + "" + m + "" + d;
};

export const formatDate = (date: Date) => {
  const t = new Date(date);
  const y = t.getFullYear();
  const m = t.getMonth() + 1 > 9 ? t.getMonth() + 1 : "0" + (t.getMonth() + 1);
  const d = t.getDate() > 9 ? t.getDate() : "0" + t.getDate();
  return y + "-" + m + "-" + d;
};
export const formatMonthDay = (date: Date) => {
  const t = new Date(date);
  const y = t.getFullYear();
  const m = t.getMonth() + 1 > 9 ? t.getMonth() + 1 : "0" + (t.getMonth() + 1);
  const d = t.getDate() > 9 ? t.getDate() : "0" + t.getDate();
  return m + "-" + d;
};
//yyyyMMddHHmmssSSS
function supp0(n: any) {
  return n < 10 ? "0" + n : n;
}
export const formatTime = (time: Date) => {
  const date = new Date(time);
  return (
    date.getFullYear().toString() +
    supp0(date.getMonth() + 1) +
    supp0(date.getDate()) +
    supp0(date.getHours()) +
    supp0(date.getMinutes()) +
    supp0(date.getSeconds()) +
    supp0(date.getMilliseconds())
  );
};

//6位-随机数
export const GetRandomNum = (Min: any, Max: any) => {
  const Range = Max - Min;
  const Rand = Math.random();
  return Min + Math.round(Rand * Range);
};

// 视频弹窗播放
export const openVideoPage = (src: string, name: string = "视频播放") => {
  window.open(src, name, "width=500,height=500,top=100");
};

export const openPage = (
  src: string,
  name: string,
  width: number,
  height: number,
  left: number,
  top: number
) => {
  window.open(
    src,
    name,
    `width=${width},height=${height},top=${top},left=${left}`
  );
};

/**
 * 绘制简单纹理（图片）
 * @param color 纹理颜色
 * @param type 纹理类型 0条纹，1渐变
 */
type TextureType = {
  color: string;
  type: 0 | 1;
  height?: number;
  tile?: number;
  direction?: 0 | 1 | 2 | 3;
};
export const drawTexture = (option: TextureType): string => {
  const { color, type } = option;
  let img = "";
  switch (type) {
    // 条纹纹理
    case 0:
      let { height, tile } = option;
      height = height ? height : 10;
      tile = tile ? tile : 5;
      img = drawStripeTexture(color, height as number, tile as number);
      break;
    // 渐变纹理
    case 1:
      let direction = option.direction;
      direction = typeof direction !== "undefined" ? direction : 0;
      img = drawGradientTexture(color, direction as 0 | 1 | 2 | 3);
      break;
    default:
      break;
  }
  return img;
};

/**
 * 绘制条形的纹理图片
 * @param color 条纹颜色
 * @param height 条纹高度及条纹之间的间隔
 * @param tile 平铺次数
 **/
const drawStripeTexture = (
  color: string,
  height: number,
  tile: number
): string => {
  const canvas = document.createElement("canvas");
  const context = canvas.getContext("2d");
  if (context) {
    // canvas（图片）高度
    const _h = tile * 2 * height;
    canvas.height = _h;
    // 横向贴图为1，宽度任意
    canvas.width = 100;
    context.fillStyle = color;
    for (let i = 0; i < tile; i++) {
      context.fillRect(0, i * 2 * height, 100, height);
    }
    return canvas.toDataURL("image/png");
  } else {
    return "";
  }
};

/**
 * 绘制渐变的纹理图片，线型渐变
 * @param color 颜色
 * @param direction 方向 0向上，1向下，2向左，3向右
 *
 */
const drawGradientTexture = (color: string, direction: 0 | 1 | 2 | 3) => {
  const canvas = document.createElement("canvas");
  const context = canvas.getContext("2d");
  if (context) {
    canvas.height = 100;
    canvas.width = 100;
    // 线型渐变起点及终点
    let location: number[] = [];
    switch (direction) {
      case 0:
        location = [0, 100, 0, 0];
        break;
      case 1:
        location = [0, 0, 0, 100];
        break;
      case 2:
        location = [0, 0, 100, 0];
        break;
      case 3:
        location = [100, 0, 0, 0];
        break;
    }
    const grd = context.createLinearGradient(
      location[0],
      location[1],
      location[2],
      location[3]
    );

    // 添加颜色
    grd.addColorStop(0, color);
    grd.addColorStop(0.6, color + "80");
    grd.addColorStop(1, "#ffffff00");
    context.fillStyle = grd;
    context.fillRect(0, 0, 100, 100);
    return canvas.toDataURL("image/png");
  } else {
    return "";
  }
};

export const hex2Rgba = (hex: string) => {
  const r = parseInt("0x" + hex.substr(1, 2));
  const g = parseInt("0x" + hex.substr(3, 2));
  const b = parseInt("0x" + hex.substr(5, 2));
  const a = hex.length === 9 ? parseInt("0x" + hex.substr(7, 2)) : 255;
  return [r, g, b, a / 255];
};

/**
 * 根据rings创建mesh图形
 * @param rings polygon坐标
 * @param color mesh 材质颜色
 * @param height mesh 高度
 */
export const createMeshGraphic = async (
  rings: number[][][],
  img: string,
  height: number
) => {
  const modules = await getModules(["esri/geometry/Mesh", "esri/Graphic"]);
  const [Mesh, Graphic] = modules;
  const graphics: any[] = [];
  rings.forEach(el => {
    // 顶点存储
    const position: number[] = [];
    // 顶点构面，三角形
    const components: number[] = [];
    // 生成着色uv坐标
    const uv: number[] = [];
    let index = 0;
    // uv坐标x轴变化值变化
    el.forEach(el => {
      // 顶点
      position.push(el[0], el[1], 0);
      position.push(el[0], el[1], height);
      // 上述顶点的uv坐标
      uv.push(0, 0);
      uv.push(0, 1);
      if (position.length >= 12) {
        components.push(index, index + 1, index + 2);
        components.push(index + 1, index + 2, index + 3);
        index += 2;
      }
    });
    // 创建mesh
    const mesh = new Mesh({
      vertexAttributes: {
        position,
        uv
      },
      components: [
        {
          faces: components,
          material: {
            colorTexture: img,
            alphaCutoff: 0
          }
        }
      ],
      spatialReference: store.spatialReference
    });
    // 生成graphic
    const graphic = new Graphic({
      geometry: mesh,
      symbol: {
        type: "mesh-3d",
        symbolLayers: [{ type: "fill" }]
      }
    });
    graphics.push(graphic);
  });
  return graphics;
};

type TextOption = {
  text: string;
  size?: number;
  color?: string;
  haloSize?: number;
  haloColor?: string;
  fontFamily?: string;
};
export const drawTextImage = (
  option: TextOption
): { img: string; width: number; height: number } | null => {
  const canvas = document.createElement("canvas");
  const context = canvas.getContext("2d");
  if (context) {
    const { text, haloSize, haloColor } = option;
    // 默认值
    let { size, color, fontFamily } = option;
    size = size ? size : 20;
    color = color ? color : "black";
    fontFamily = fontFamily ? fontFamily : "Microsoft YaHei";
    context.font = `${size}px ${fontFamily}`;
    const width = context.measureText(text).width;
    canvas.width = width;
    canvas.height = size * 2;
    context.fillStyle = color;
    context.textAlign = "center";
    context.textBaseline = "middle";
    context.font = `${size}px ${fontFamily}`;
    // 先绘制边框
    if (haloColor && haloSize) {
      context.lineWidth = haloSize;
      context.strokeStyle = haloColor;
      context.strokeText(text, width / 2, size);
    }
    context.fillText(text, width / 2, size);
    const img = canvas.toDataURL("image/png");
    context.clearRect(0, 0, width, size * 2);
    return { img, width, height: 2 * size };
  } else {
    return null;
  }
};

// 有效期两小时
export const getArcGISToken = (
  url: string, // ip+hose
  username: string,
  password: string
) => {
  const promise = new Promise<string>((resolve, reject) => {
    const qs = require("qs");
    axios
      .post(
        url,
        qs.stringify({
          username,
          password,
          client: "requestip",
          expiration: 120,
          f: "json"
        })
      )
      .then(res => {
        if (res.status === 200) {
          const token = res.data.token;
          resolve(token);
        } else {
          reject(new Error("获取token失败"));
        }
      });
  });
  return promise;
};

export function mouseDownLeft(event: any, id: string, sTop: number, sRight: number) {
  const oldX = event.pageX;
  const oldY = event.pageY;
  const contain: HTMLElement | any = document.getElementById(id);
  const oldTop = contain.style.top;
  const oldRight = contain.style.left;
  document.onmousemove = function (e) {
    const left = e.pageX - oldX;
    const top = e.pageY - oldY;
    moveDivLeft(oldTop, oldRight, left, top, contain, sTop, sRight);
  }
  document.onmouseup = function () {
    document.onmousemove = null;
    document.onmouseup = null;
  }
}

function moveDivLeft(oldTop: any, oldRight: any, left: number, top: number, contain: HTMLElement | any, sTop: number, sRight: number) {
  if (oldTop === '' || oldRight === '') {
    const newTop = sTop + top;
    const newLeft = sRight + left;
    if (newTop > 80 && newTop < window.innerHeight - 50) {
      contain.style.top = newTop + 'px';
    }
    if (newLeft > 0 && newLeft < window.innerWidth) {
      contain.style.left = newLeft + 'px';
    }
  } else {
    const newTop = parseInt(oldTop) + top;
    const newLeft = parseInt(oldRight) + left;
    if (newTop > 80 && newTop < window.innerHeight - 50) {
      contain.style.top = newTop + 'px';
    }
    if (newLeft > 0 && newLeft < window.innerWidth) {
      contain.style.left = newLeft + 'px';
    }
  }
}

export function changeExtent(extent: any) {
  const x = extent.xmax - extent.xmin;
  const y = extent.ymax - extent.ymin;
  extent.xmin = extent.xmin - x / 2;
  extent.xmax = extent.xmax + x / 2;
  extent.ymin = extent.ymin - y / 2;
  extent.ymax = extent.ymax + y / 2;
  return extent;
}